<!DOCTYPE html>
<html>
<head>
    <!-- hexo-inject:begin --><!-- hexo-inject:end --><title>博望</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css">
    <script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    
<link rel="stylesheet" href="/css/prism.css">
 
    
<script src="/js/prism.js"></script>

    
    
<link rel="stylesheet" href="/css/index.css">
 
    
<script src="/js/search.js"></script>



     
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML" async></script>
        <script type="text/x-mathjax-config">
            MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
        </script>
     

     
        <script src="//lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js"> </script>
        
<script src="/js/fancybox.js"></script>

    

    <script type="text/javascript">
        var search_path = "search.xml";
        if (search_path.length == 0) {
            search_path = "search.xml";
        }
        var path = "/" + search_path;
        searchFunc(path, 'local-search-input', 'local-search-result');
    </script>
<!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.28.0/themes/prism.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.1.0"><!-- hexo-inject:begin --><!-- hexo-inject:end --></head>

    <style>
        .row2 {
            /* --bs-gutter-x: 2.5rem;
            --bs-gutter-y: 0;
            display: flex;
            flex-wrap: wrap;
            margin-top: calc(var(--bs-gutter-y) * -20);
            margin-right: calc(var(--bs-gutter-x) * -2);
            margin-left: calc(var(--bs-gutter-x) * -2); */
        }

        .row-0 {
            width: 0;
        }
    </style>

    <body id="body">
        <!-- hexo-inject:begin --><!-- hexo-inject:end --><!-- 导航栏 -->
        <nav class="navbar navbar-expand-md navbar-dark mb-4 pt-3 pb-3">
    <div class="container" style="display: flex;flex-direction: row;align-items: flex-end;">
        <div style="display: flex;flex-direction: column;">
            <a class="navbar-brand" style='font: bold 29px "Times New Roman", Georgia, Times, sans-serif;
        color: #555;' href="/ ">
                博望
            </a>
            <span style="padding-bottom:7px;padding-right:20px">
                博望不熄
            </span>
        </div>

        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
            aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarCollapse">
            <ul class="navbar-nav me-auto mb-2 mb-md-0" style="color: #555;">
                
 
 

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/">
            <i class="fa fa-home "> </i> 主页
        </a>
    </li>

    <li class="nav-item">
        <a class="nav-link" style="color: #555;" href="/archives">
            <i class="fa fa-archive" "> </i> 归档
        </a>
    </li>
 

            </ul>

            
                <form class="d-flex">
                    <button class="btn text-muted fa fa-search d-none d-md-block d-lg-block" disabled></button>
                    <input id="local-search-input" class="form-control me-2 pe-4" type="search"
                        placeholder="搜索 " aria-label="Search">
                </form>
                

                    <ul class="navbar-nav">
                        
 

                    </ul>
        </div>
    </div>
</nav>

            <main class="container">
                <div class="row row2 pt-3">
                    <!-- 文章 -->
                    <div id="content" class="col-md-12">
                        <div class="markdown-section">
                            <!-- 搜索结果 -->
                            <div id="local-search-result"></div>
                            <!-- 博客详情 -->
<p class="h1">QuickJS JavaScript世界的原始原型对象的建立</p>

<div class="pb-3">
    <i class="fa fa-calendar p-1"></i>
    2022/05/16 09:07:50 

    <i class="fa fa-folder-open p-1"> </i> 
    <span class="tag-hover">
         
    </span>

    <i class="fa fa-tag p-1"> </i>
    <span class="tag-hover">
        
            <a href="/tags/QuickJS/" class="link-dark text-decoration-none"> 
                QuickJS 
            </a>
        
    </span>
</div>

<h2 id="标题面向对象与原型链"><a href="#标题面向对象与原型链" class="headerlink" title="标题面向对象与原型链"></a>标题面向对象与原型链</h2><p>JavaScript中，对象的继承是通过原型链的方式来实现。一个子对象可以从父对象中继承其父对象的属性和方法。具体的机制是：当访问一个对象的属性或方法时，首先会查找该对象是否有对应的属性或方法。如果有，就调用其属性和方法。如果没有，就访问其原型对象，查看原型对象中是否存在。如果存在，就调用该属性或方法。如果没有，继续寻找原型对象的原型对象。直到访问到原始原型对象为止。需要注意的是，所有的对象继承自原始原型对象。<br>在QuickJS中，JS对象反映在引擎中，是一个JSObject结构体。原始原型对象也是一个JSObject结构体。它被保存在JSContext的class_proto中。class_proto是一个数组，保存了所有JavaScript的原始原型对象，如Object、Array、Function等。本文主要研究原始原型对象的建立，其它暂不做深究。<br>原始对象的创建是在 JS_AddIntrinsicBasicObjects 方法中。使用 JS_NewObjectProto 来创建。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">JS_MKVAL</span><span class="token expression"><span class="token punctuation">(</span>tag<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token punctuation">(</span>JSValue<span class="token punctuation">)</span><span class="token punctuation">&#123;</span> <span class="token punctuation">(</span>JSValueUnion<span class="token punctuation">)</span><span class="token punctuation">&#123;</span> <span class="token punctuation">.</span>int32 <span class="token operator">=</span> val <span class="token punctuation">&#125;</span><span class="token punctuation">,</span> tag <span class="token punctuation">&#125;</span></span></span>
JS_TAG_NULL        <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">JS_NULL</span>      <span class="token expression"><span class="token function">JS_MKVAL</span><span class="token punctuation">(</span>JS_TAG_NULL<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span></span></span>

<span class="token comment">/* Minimum amount of objects to be able to compile code and display
   error messages. No JSAtom should be allocated by this function. */</span>
<span class="token comment">// 添加固有基础对象</span>
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">JS_AddIntrinsicBasicObjects</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    JSValue proto<span class="token punctuation">;</span>
    <span class="token keyword">int</span> i<span class="token punctuation">;</span>

    ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_OBJECT<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">JS_NewObjectProto</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> JS_NULL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    ctx<span class="token operator">-></span>function_proto <span class="token operator">=</span> <span class="token function">JS_NewCFunction3</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> js_function_proto<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span>
                                           JS_CFUNC_generic<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span>
                                           ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_OBJECT<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_BYTECODE_FUNCTION<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">JS_DupValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>function_proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
    ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ERROR<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">JS_NewObject</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">if</span> <span class="token expression"><span class="token number">0</span></span></span>
    <span class="token comment">/* these are auto-initialized from js_error_proto_funcs,
       but delaying might be a problem */</span>
    <span class="token function">JS_DefinePropertyValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ERROR<span class="token punctuation">]</span><span class="token punctuation">,</span> JS_ATOM_name<span class="token punctuation">,</span>
                           <span class="token function">JS_AtomToString</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> JS_ATOM_Error<span class="token punctuation">)</span><span class="token punctuation">,</span>
                           JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_CONFIGURABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">JS_DefinePropertyValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ERROR<span class="token punctuation">]</span><span class="token punctuation">,</span> JS_ATOM_message<span class="token punctuation">,</span>
                           <span class="token function">JS_AtomToString</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> JS_ATOM_empty_string<span class="token punctuation">)</span><span class="token punctuation">,</span>
                           JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_CONFIGURABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <span class="token function">JS_SetPropertyFunctionList</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ERROR<span class="token punctuation">]</span><span class="token punctuation">,</span>
                               js_error_proto_funcs<span class="token punctuation">,</span>
                               <span class="token function">countof</span><span class="token punctuation">(</span>js_error_proto_funcs<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> JS_NATIVE_ERROR_COUNT<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        proto <span class="token operator">=</span> <span class="token function">JS_NewObjectProto</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ERROR<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">JS_DefinePropertyValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> JS_ATOM_name<span class="token punctuation">,</span>
                               <span class="token function">JS_NewAtomString</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> native_error_name<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                               JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_CONFIGURABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">JS_DefinePropertyValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> JS_ATOM_message<span class="token punctuation">,</span>
                               <span class="token function">JS_AtomToString</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> JS_ATOM_empty_string<span class="token punctuation">)</span><span class="token punctuation">,</span>
                               JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_CONFIGURABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
        ctx<span class="token operator">-></span>native_error_proto<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> proto<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token comment">/* the array prototype is an array */</span>
    ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ARRAY<span class="token punctuation">]</span> <span class="token operator">=</span>
        <span class="token function">JS_NewObjectProtoClass</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_OBJECT<span class="token punctuation">]</span><span class="token punctuation">,</span>
                               JS_CLASS_ARRAY<span class="token punctuation">)</span><span class="token punctuation">;</span>

    ctx<span class="token operator">-></span>array_shape <span class="token operator">=</span> <span class="token function">js_new_shape2</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_proto_obj</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_ARRAY<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                                     JS_PROP_INITIAL_HASH_SIZE<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">add_shape_property</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token operator">&amp;</span>ctx<span class="token operator">-></span>array_shape<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span>
                       JS_ATOM_length<span class="token punctuation">,</span> JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_LENGTH<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* XXX: could test it on first context creation to ensure that no
       new atoms are created in JS_AddIntrinsicBasicObjects(). It is
       necessary to avoid useless renumbering of atoms after
       JS_EvalBinary() if it is done just after
       JS_AddIntrinsicBasicObjects(). */</span>
    <span class="token comment">//    assert(ctx->rt->atom_count == JS_ATOM_END);</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<h2 id="JS-NewObjectProto"><a href="#JS-NewObjectProto" class="headerlink" title="JS_NewObjectProto"></a>JS_NewObjectProto</h2><p>JS_NewObjectProto 方法用于根据原型来创建对象。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c">JSValue <span class="token function">JS_NewObjectProto</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> JSValueConst proto<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token function">JS_NewObjectProtoClass</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> JS_CLASS_OBJECT<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/* WARNING: proto must be an object or JS_NULL */</span>
JSValue <span class="token function">JS_NewObjectProtoClass</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> JSValueConst proto_val<span class="token punctuation">,</span>
                               JSClassID class_id<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    JSShape <span class="token operator">*</span>sh<span class="token punctuation">;</span>
    JSObject <span class="token operator">*</span>proto<span class="token punctuation">;</span>
    <span class="token comment">//1. 根据传入的 JSValue 获取 JSObject - 原型对象</span>
    <span class="token comment">// 当前场景下返回的proto是NULL</span>
    proto <span class="token operator">=</span> <span class="token function">get_proto_obj</span><span class="token punctuation">(</span>proto_val<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//2. 据原型对象获取 shape</span>
    sh <span class="token operator">=</span> <span class="token function">find_hashed_shape_proto</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>sh<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">// 如果shape存在，就直接使用已经有的shape</span>
        sh <span class="token operator">=</span> <span class="token function">js_dup_shape</span><span class="token punctuation">(</span>sh<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
        <span class="token comment">// 如果不存在，就创建一个新的shape</span>
        <span class="token comment">// 当前场景下，创建的JSShape的proto值为NULL</span>
        sh <span class="token operator">=</span> <span class="token function">js_new_shape</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>sh<span class="token punctuation">)</span>
            <span class="token keyword">return</span> JS_EXCEPTION<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">//3. 根据shape创建对象</span>
    <span class="token keyword">return</span> <span class="token function">JS_NewObjectFromShape</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> sh<span class="token punctuation">,</span> class_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>


<span class="token keyword">static</span> JSValue <span class="token function">JS_NewObjectFromShape</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> JSShape <span class="token operator">*</span>sh<span class="token punctuation">,</span> JSClassID class_id<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    JSObject <span class="token operator">*</span>p<span class="token punctuation">;</span>

    <span class="token function">js_trigger_gc</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>JSObject<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 首先为对象分配内存</span>
    p <span class="token operator">=</span> <span class="token function">js_malloc</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>JSObject<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token operator">!</span>p<span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token keyword">goto</span> fail<span class="token punctuation">;</span>
    <span class="token comment">// 设置对象的class id</span>
    p<span class="token operator">-></span>class_id <span class="token operator">=</span> class_id<span class="token punctuation">;</span>
    <span class="token comment">// </span>
    p<span class="token operator">-></span>extensible <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
    <span class="token comment">// 释放标识 only used when freeing objects with cycles </span>
    p<span class="token operator">-></span>free_mark <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>is_exotic <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>fast_array <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>is_constructor <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>is_uncatchable_error <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>tmp_mark <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>is_HTMLDDA <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>first_weak_ref <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    p<span class="token operator">-></span>u<span class="token punctuation">.</span>opaque <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    <span class="token comment">// 设置对象的shape</span>
    p<span class="token operator">-></span>shape <span class="token operator">=</span> sh<span class="token punctuation">;</span>
    <span class="token comment">// 根据shape，为对象的属性值申请内存（用于存储对象属性具体的值和setter getter）</span>
    p<span class="token operator">-></span>prop <span class="token operator">=</span> <span class="token function">js_malloc</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>JSProperty<span class="token punctuation">)</span> <span class="token operator">*</span> sh<span class="token operator">-></span>prop_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 确保对象属性内存分配成功</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token operator">!</span>p<span class="token operator">-></span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token function">js_free</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span>
    fail<span class="token operator">:</span>
        <span class="token function">js_free_shape</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> sh<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> JS_EXCEPTION<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token comment">//根据对象的class_id,分别进行一些相关类型的初始化</span>
    <span class="token keyword">switch</span><span class="token punctuation">(</span>class_id<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">case</span> JS_CLASS_OBJECT<span class="token operator">:</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_ARRAY<span class="token operator">:</span>
        <span class="token punctuation">&#123;</span>
            JSProperty <span class="token operator">*</span>pr<span class="token punctuation">;</span>
            p<span class="token operator">-></span>is_exotic <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
            p<span class="token operator">-></span>fast_array <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
            p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>u<span class="token punctuation">.</span>values <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
            p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>u1<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token comment">/* the length property is always the first one */</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>sh <span class="token operator">==</span> ctx<span class="token operator">-></span>array_shape<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                pr <span class="token operator">=</span> <span class="token operator">&amp;</span>p<span class="token operator">-></span>prop<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
                <span class="token comment">/* only used for the first array */</span>
                <span class="token comment">/* cannot fail */</span>
                pr <span class="token operator">=</span> <span class="token function">add_property</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> p<span class="token punctuation">,</span> JS_ATOM_length<span class="token punctuation">,</span>
                                  JS_PROP_WRITABLE <span class="token operator">|</span> JS_PROP_LENGTH<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">&#125;</span>
            pr<span class="token operator">-></span>u<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token function">JS_NewInt32</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_C_FUNCTION<span class="token operator">:</span>
        p<span class="token operator">-></span>prop<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>u<span class="token punctuation">.</span>value <span class="token operator">=</span> JS_UNDEFINED<span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_ARGUMENTS<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_UINT8C_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_INT8_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_UINT8_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_INT16_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_UINT16_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_INT32_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_UINT32_ARRAY<span class="token operator">:</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">CONFIG_BIGNUM</span></span>
    <span class="token keyword">case</span> JS_CLASS_BIG_INT64_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_BIG_UINT64_ARRAY<span class="token operator">:</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
    <span class="token keyword">case</span> JS_CLASS_FLOAT32_ARRAY<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_FLOAT64_ARRAY<span class="token operator">:</span>
        p<span class="token operator">-></span>is_exotic <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
        p<span class="token operator">-></span>fast_array <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>u<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_DATAVIEW<span class="token operator">:</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>u<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>array<span class="token punctuation">.</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_NUMBER<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_STRING<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_BOOLEAN<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_SYMBOL<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_DATE<span class="token operator">:</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">CONFIG_BIGNUM</span></span>
    <span class="token keyword">case</span> JS_CLASS_BIG_INT<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_BIG_FLOAT<span class="token operator">:</span>
    <span class="token keyword">case</span> JS_CLASS_BIG_DECIMAL<span class="token operator">:</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>object_data <span class="token operator">=</span> JS_UNDEFINED<span class="token punctuation">;</span>
        <span class="token keyword">goto</span> set_exotic<span class="token punctuation">;</span>
    <span class="token keyword">case</span> JS_CLASS_REGEXP<span class="token operator">:</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>regexp<span class="token punctuation">.</span>pattern <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
        p<span class="token operator">-></span>u<span class="token punctuation">.</span>regexp<span class="token punctuation">.</span>bytecode <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
        <span class="token keyword">goto</span> set_exotic<span class="token punctuation">;</span>
    <span class="token keyword">default</span><span class="token operator">:</span>
    set_exotic<span class="token operator">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token operator">-></span>class_array<span class="token punctuation">[</span>class_id<span class="token punctuation">]</span><span class="token punctuation">.</span>exotic<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            p<span class="token operator">-></span>is_exotic <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">// 为对象设置引用计数</span>
    p<span class="token operator">-></span>header<span class="token punctuation">.</span>ref_count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token comment">// 将这个对象加入到回收监控中</span>
    <span class="token function">add_gc_object</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> <span class="token operator">&amp;</span>p<span class="token operator">-></span>header<span class="token punctuation">,</span> JS_GC_OBJ_TYPE_JS_OBJECT<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token function">JS_MKPTR</span><span class="token punctuation">(</span>JS_TAG_OBJECT<span class="token punctuation">,</span> p<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">JS_VALUE_GET_PTR</span><span class="token expression"><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">.</span>u<span class="token punctuation">.</span>ptr<span class="token punctuation">)</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">JS_VALUE_GET_OBJ</span><span class="token expression"><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>JSObject <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">JS_VALUE_GET_PTR</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">)</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">JS_VALUE_GET_TAG</span><span class="token expression"><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">int32_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">.</span>tag<span class="token punctuation">)</span></span></span>

<span class="token comment">// 获取JSValue的原型对象</span>
<span class="token keyword">static</span> JSObject <span class="token operator">*</span><span class="token function">get_proto_obj</span><span class="token punctuation">(</span>JSValueConst proto_val<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token comment">// 判单JSValue是否是Object，如果不是，直接返回NULL</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">JS_VALUE_GET_TAG</span><span class="token punctuation">(</span>proto_val<span class="token punctuation">)</span> <span class="token operator">!=</span> JS_TAG_OBJECT<span class="token punctuation">)</span>
        <span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    <span class="token keyword">else</span>
        <span class="token comment">//根据 proto_val 获取它的对象 </span>
        <span class="token keyword">return</span> <span class="token function">JS_VALUE_GET_OBJ</span><span class="token punctuation">(</span>proto_val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/* find a hashed empty shape matching the prototype. Return NULL if
   not found */</span>
<span class="token comment">//根据 JSObject 获取它的 JSShape</span>
<span class="token keyword">static</span> JSShape <span class="token operator">*</span><span class="token function">find_hashed_shape_proto</span><span class="token punctuation">(</span>JSRuntime <span class="token operator">*</span>rt<span class="token punctuation">,</span> JSObject <span class="token operator">*</span>proto<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    JSShape <span class="token operator">*</span>sh1<span class="token punctuation">;</span>
    <span class="token class-name">uint32_t</span> h<span class="token punctuation">,</span> h1<span class="token punctuation">;</span>

    h <span class="token operator">=</span> <span class="token function">shape_initial_hash</span><span class="token punctuation">(</span>proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
    h1 <span class="token operator">=</span> <span class="token function">get_shape_hash</span><span class="token punctuation">(</span>h<span class="token punctuation">,</span> rt<span class="token operator">-></span>shape_hash_bits<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span>sh1 <span class="token operator">=</span> rt<span class="token operator">-></span>shape_hash<span class="token punctuation">[</span>h1<span class="token punctuation">]</span><span class="token punctuation">;</span> sh1 <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> sh1 <span class="token operator">=</span> sh1<span class="token operator">-></span>shape_hash_next<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>sh1<span class="token operator">-></span>hash <span class="token operator">==</span> h <span class="token operator">&amp;&amp;</span>
            sh1<span class="token operator">-></span>proto <span class="token operator">==</span> proto <span class="token operator">&amp;&amp;</span>
            sh1<span class="token operator">-></span>prop_count <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token keyword">return</span> sh1<span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 将申请的内存强转为JSShape</span>
<span class="token keyword">static</span> <span class="token keyword">inline</span> JSShape <span class="token operator">*</span><span class="token function">get_shape_from_alloc</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>sh_alloc<span class="token punctuation">,</span> <span class="token class-name">size_t</span> hash_size<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>JSShape <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> <span class="token operator">*</span><span class="token punctuation">)</span>sh_alloc <span class="token operator">+</span> hash_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/* create a new empty shape with prototype 'proto' */</span>
<span class="token keyword">static</span> no_inline JSShape <span class="token operator">*</span><span class="token function">js_new_shape2</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> JSObject <span class="token operator">*</span>proto<span class="token punctuation">,</span>
                                        <span class="token keyword">int</span> hash_size<span class="token punctuation">,</span> <span class="token keyword">int</span> prop_size<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    JSRuntime <span class="token operator">*</span>rt <span class="token operator">=</span> ctx<span class="token operator">-></span>rt<span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token operator">*</span>sh_alloc<span class="token punctuation">;</span>
    JSShape <span class="token operator">*</span>sh<span class="token punctuation">;</span>

    <span class="token comment">/* resize the shape hash table if necessary */</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> <span class="token punctuation">(</span>rt<span class="token operator">-></span>shape_hash_count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">></span> rt<span class="token operator">-></span>shape_hash_size<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token function">resize_shape_hash</span><span class="token punctuation">(</span>rt<span class="token punctuation">,</span> rt<span class="token operator">-></span>shape_hash_bits <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    sh_alloc <span class="token operator">=</span> <span class="token function">js_malloc</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">get_shape_size</span><span class="token punctuation">(</span>hash_size<span class="token punctuation">,</span> prop_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>sh_alloc<span class="token punctuation">)</span>
        <span class="token keyword">return</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
    sh <span class="token operator">=</span> <span class="token function">get_shape_from_alloc</span><span class="token punctuation">(</span>sh_alloc<span class="token punctuation">,</span> hash_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>header<span class="token punctuation">.</span>ref_count <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token function">add_gc_object</span><span class="token punctuation">(</span>rt<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sh<span class="token operator">-></span>header<span class="token punctuation">,</span> JS_GC_OBJ_TYPE_SHAPE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>proto<span class="token punctuation">)</span>
        <span class="token function">JS_DupValue</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> <span class="token function">JS_MKPTR</span><span class="token punctuation">(</span>JS_TAG_OBJECT<span class="token punctuation">,</span> proto<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>proto <span class="token operator">=</span> proto<span class="token punctuation">;</span>
    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token function">prop_hash_end</span><span class="token punctuation">(</span>sh<span class="token punctuation">)</span> <span class="token operator">-</span> hash_size<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token function">prop_hash_end</span><span class="token punctuation">(</span>sh<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">*</span>
           hash_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>prop_hash_mask <span class="token operator">=</span> hash_size <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>prop_size <span class="token operator">=</span> prop_size<span class="token punctuation">;</span>
    sh<span class="token operator">-></span>prop_count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>deleted_prop_count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    
    <span class="token comment">/* insert in the hash table */</span>
    <span class="token comment">// 设置JSShape的hash</span>
    sh<span class="token operator">-></span>hash <span class="token operator">=</span> <span class="token function">shape_initial_hash</span><span class="token punctuation">(</span>proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
    sh<span class="token operator">-></span>is_hashed <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
    sh<span class="token operator">-></span>has_small_array_index <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
    <span class="token function">js_shape_hash_link</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>rt<span class="token punctuation">,</span> sh<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> sh<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/* 
    1. 如果需要调大装载shape的hash的表
    2. 为新shape分配内存
    3. 将申请的内存转化为JSShape
    4. 设置引用计数和回收
    5. 为JSShape设置它的原型对象
    6. 将JSShape的hash段清空
    7. 设置JSShape的属性数量和大小
    8. 设置JSShape的hash
*/</span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">JS_PROP_INITIAL_SIZE</span> <span class="token expression"><span class="token number">2</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">JS_PROP_INITIAL_HASH_SIZE</span> <span class="token expression"><span class="token number">4</span> </span><span class="token comment">/* must be a power of two */</span></span>
<span class="token keyword">static</span> JSShape <span class="token operator">*</span><span class="token function">js_new_shape</span><span class="token punctuation">(</span>JSContext <span class="token operator">*</span>ctx<span class="token punctuation">,</span> JSObject <span class="token operator">*</span>proto<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token function">js_new_shape2</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> JS_PROP_INITIAL_HASH_SIZE<span class="token punctuation">,</span>
                         JS_PROP_INITIAL_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>


<span class="token comment">/* same magic hash multiplier as the Linux kernel */</span>
<span class="token keyword">static</span> <span class="token class-name">uint32_t</span> <span class="token function">shape_hash</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> h<span class="token punctuation">,</span> <span class="token class-name">uint32_t</span> val<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>h <span class="token operator">+</span> val<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">0x9e370001</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/* truncate the shape hash to 'hash_bits' bits */</span>
<span class="token keyword">static</span> <span class="token class-name">uint32_t</span> <span class="token function">get_shape_hash</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> h<span class="token punctuation">,</span> <span class="token keyword">int</span> hash_bits<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> h <span class="token operator">>></span> <span class="token punctuation">(</span><span class="token number">32</span> <span class="token operator">-</span> hash_bits<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/** 获取shape的hash */</span>
<span class="token keyword">static</span> <span class="token class-name">uint32_t</span> <span class="token function">shape_initial_hash</span><span class="token punctuation">(</span>JSObject <span class="token operator">*</span>proto<span class="token punctuation">)</span>
<span class="token punctuation">&#123;</span>
    <span class="token class-name">uint32_t</span> h<span class="token punctuation">;</span>
    h <span class="token operator">=</span> <span class="token function">shape_hash</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>proto<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>proto<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">4</span><span class="token punctuation">)</span>
        h <span class="token operator">=</span> <span class="token function">shape_hash</span><span class="token punctuation">(</span>h<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>proto <span class="token operator">>></span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> h<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>JSObject是Javascript代码中的对象在QuickJS引擎中的实现。原始原型对象是使用 JS_NewObjectProto 来创建。JS_NewObjectProto 调用了 JS_NewObjectProtoClass 函数实现创建过程。</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//1. 使用JS_NewObjectProto创建原始原型对象，参数是ctx和JS_NULL</span>
ctx<span class="token operator">-></span>class_proto<span class="token punctuation">[</span>JS_CLASS_OBJECT<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">JS_NewObjectProto</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> JS_NULL<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//2. 调用JS_NewObjectProtoClass完成原始原型对象的创建</span>
<span class="token function">JS_NewObjectProtoClass</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> proto<span class="token punctuation">,</span> JS_CLASS_OBJECT<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>调用时，我们传入了第三个参数，分别是ctx，JS_NULL 和 JS_CLASS_OBJECT 。<br>JS_NewObjectProtoClass 中分三步创建原型对象。<br>第一步，根据传入的 proto（此处为JS_NULL） 获取它的原型对象。根据其调用的 get_proto_obj 方法，可知，当JSValue不是JSObject时，返回的是NULL。<br>第二步，根据获取的原型对象，获取其JSShape。使用 find_hashed_shape_proto 方法来获取。如果shape不存在，就根据原型对象，创建一个新的JSShape。在当前场景中，proto是NULL，JSShape也同样不存在，因此是根据其原型对象创建了新的JSShape。根据创建函数 js_new_shape2 来源码来看，该JSShape的原型对象是NULL。<br>第三步，根据 JSShape 创建原型对象。此处，将新创建的JSObject的shape设置为第二步获取的JSShape。<br>据此可知，JSObject持有JSShape，而JSShape是根据原型对象—JSObject 创建而来的。他们并不是一个环形互相引用关系，是一个链表的第次持有关系。<br>最后，将刚刚创建的原型对象放入 ctx-&gt;class_proto[JS_CLASS_OBJECT] 中。后续JavaScript环境中，创建JSObject时，都将直接或间接的获取使用这个对象。</p>
 

<div class="p-2 pe-4">
     
        <a href="/2022/05/16/QuickJS%E4%BB%A3%E7%A0%81%E8%A7%A3%E6%9E%90%E9%98%B6%E6%AE%B5%E5%85%B3%E9%94%AE%E7%BB%93%E6%9E%84%E4%BD%93/" class="btn btn-outline-secondary btn-sm float-start">
            <small>
                < 上一篇：QuickJS 代码解析阶段关键结构体
            </small>
        </a>
     
     
        <a href="/2022/05/12/QuickJS%E6%95%B0%E5%AD%97%E5%AD%97%E9%9D%A2%E9%87%8F/" class="btn btn-outline-secondary btn-sm float-end" >
            <small>
                下一篇：QuickJS数字字面量 >
            </small>
        </a>
     
</div>
                        </div>
                    </div>

                    <!-- sidebar -->
                    <div id="slidebar">
                        <div class="border-auto ps-2 pe-1 pb-2 pt-2">
    
        <!-- 侧边栏 分类 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-folder-open pe-2"></i>分类
        
    </h6>
    <div class="card-body">
        <ul class="list-group border-0">
            
            
             
            <a class="list-group-item border-0 pt-0 pb-0 ps-1" href="/categories/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">3</span>
            </a>
              
        </ul>

        <ul class="list-group border-0 collapse" id="category">
            
        </ul>
    </div>
</div>

 
    
        <!-- 侧边栏 标签 -->
<div class="card mb-3">
    <h6 class="card-header tag-hover"><i class="fa fa-tag pe-2"></i>标签
        
    </h6>

    <div class="card-body tag-hover">
        
        
             
            <a class="text-decoration-none border-0 d-inline-flex link-dark pt-0 pb-0 p-0" href="/tags/QuickJS/ ">
                QuickJS <span class="badge bg-secondary float-end m-1">6</span>
            </a>
          

        <span id="tags" class="collapse">
            
        </span>
    </div>
</div>
 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-clock-o pe-2"></i>最近文章</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS-JSString-JSAtom/ ">
                    <small> QuickJS JSString&JSAtom </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E5%AD%97%E8%8A%82%E7%A0%81%E6%89%93%E5%8D%B0/ ">
                    <small> QuickJS字节码打印 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/05/QuickJS%E6%93%8D%E4%BD%9C%E7%A0%81/ ">
                    <small> QuickJS操作码 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/12/QuickJS%E6%95%B0%E5%AD%97%E5%AD%97%E9%9D%A2%E9%87%8F/ ">
                    <small> QuickJS数字字面量 </small>
                </a>
            
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6" style="margin-bottom: 10px;" href="/2022/05/16/QuickJS-JavaScript%E4%B8%96%E7%95%8C%E7%9A%84%E5%8E%9F%E5%A7%8B%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BB%BA%E7%AB%8B/ ">
                    <small> QuickJS JavaScript世界的原始原型对象的建立 </small>
                </a>
            
             
        </ul>
    </div>
</div> 
    
        <div class="card mb-3">
    <h6 class="card-header"><i class="fa fa-link pe-2"></i>友情链接</h6>
    <div class="card-body tag-hover">
        <ul class="list-group border-0">
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://blog.csdn.net/jayyuz ">
                    <small>CSDN</small>
                </a>
            
                <a class="list-group-item border-0 pt-0 pb-0 ps-1 fs-6 text" target="_blank" rel="noopener" href="https://smartlink.xin ">
                    <small>Smartlink</small>
                </a>
             
        </ul>
    </div>
</div> 
    
</div>
                    </div>
                </div>
            </main>


            <!-- footer -->
            <footer id="footer" class="bg-dark pt-3 pb-0 mt-5">
    <div class="container pb-4 pt-4 text-center">
        <p class="text-muted tag-hover"> Copyright © 2022 <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://hexo.io"> SmartLink </a><br> <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> Hexo </a> Theme <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://github.com/smile-yan/hexo-theme-heyan"> heyan </a> 
            <br>
            <a class="link-secondary text-decoration-none" target="_blank" rel="noopener" href="https://beian.miit.gov.cn/#/Integrated/index">
                 
            </a>
        </p>
    </div>
</footer>
    <!-- hexo injector body_end start -->
<script src="/assets/prism-bundle.js"></script>
<script src="/assets/prism-plus.js" data-pjax=""></script>
<!-- hexo injector body_end end --><!-- hexo-inject:begin --><!-- hexo-inject:end --></body>
    <script>
        // 获取屏幕高度 document.documentElement.clientHeight
        console.log(document.documentElement.clientHeight);
        // 获取屏幕宽度 document.documentElement.clientWidth
        console.log(document.documentElement.clientWidth);
        if (document.documentElement.clientHeight > document.documentElement.clientWidth) {
            console.log('remove slidebar')
            document.getElementById("slidebar").remove()
            document.getElementById("content").className = "col-md-12";//单个class  
        } else {
            document.getElementById("slidebar").className = "col-md-2";//单个class  
            document.getElementById("content").className = "col-md-10";//单个class  
        }
    </script>
    <!-- https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.birds.min.js -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.dots.min.js"></script>
    <script>
        VANTA.DOTS({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            scaleMobile: 1.00,
            size: 2.20,
            spacing: 13.00
        })
    </script> -->

    <!-- <script src="https://cdn.jsdelivr.net/npm/vanta@0.5.22/dist/vanta.clouds2.min.js"></script>
    <script>
        VANTA.CLOUDS2({
            el: "#footer",
            mouseControls: true,
            touchControls: true,
            gyroControls: false,
            minHeight: 200.00,
            minWidth: 200.00,
            scale: 1.00,
            speed: 2.10,
            texturePath: "https://www.vantajs.com/gallery/noise.png"
        })
    </script> -->

</html>